import json
import logging.handlers
import os

import pymysql
from bs4 import BeautifulSoup

from config import DIR_PATH  # 导入配置文件中的项目根目录路径


def com_assert(result, expect_code=None, expect_json=None, expect_text=None):
    """
    通用断言函数，用于验证API响应结果

    参数:
        result: requests.Response对象，包含API响应
        expect_code: 预期HTTP状态码
        expect_json: 预期响应JSON中的描述字段
        expect_text: 预期响应文本中包含的字符串
    """
    # 状态码断言
    if expect_code:
        # 验证实际状态码是否等于预期状态码
        assert result.status_code == expect_code, "状态码断言错误，期望状态码{}不等于实际状态码{}" \
            .format(expect_code, result.status_code)

    # JSON描述断言
    if expect_json:
        # 验证响应JSON中的description字段是否包含预期值
        assert expect_json in result.json().get("description"), "JSON断言错误，期望值{}不包含在实际值{}中" \
            .format(expect_json, result.json().get("description"))

    # 文本内容断言
    if expect_text:
        # 验证响应文本中是否包含预期字符串
        assert expect_text in result.text, "文本断言错误，期望文本{}不包含在实际文本中" \
            .format(expect_text)


def read_json(filename, key):
    """
    读取JSON文件中的数据

    参数:
        filename: JSON文件名
        key: JSON中要读取的键名

    返回:
        list: 包含指定键下所有值的列表
    """
    # 构建文件完整路径
    filepath = DIR_PATH + os.sep + "data" + os.sep + filename

    arrys = []  # 存储读取的数据

    # 打开并读取JSON文件
    with open(filepath, "r", encoding="utf8") as f:
        # 获取指定键下的数据列表
        data_list = json.load(f).get(key)

        # 遍历列表中的每个字典
        for data in data_list:
            # 提取字典的值（跳过第一个键）
            values = tuple(data.values())[1:]
            arrys.append(values)

    return arrys


class GetLog:
    """日志记录器工厂类（单例模式）"""

    # 类变量，用于存储日志记录器实例
    log = None

    @classmethod
    def get_log(cls):
        """
        创建并配置日志记录器

        使用单例模式确保整个应用中只有一个日志记录器实例

        返回:
            logging.Logger: 配置好的日志记录器对象
        """
        # 检查是否已经创建过日志记录器
        if cls.log is None:
            # 创建新的日志记录器实例
            cls.log = logging.getLogger()

            # 设置日志级别为INFO（只记录INFO及以上级别的日志）
            cls.log.setLevel(logging.INFO)

            # 构建日志文件路径
            filename = DIR_PATH + os.sep + "log" + os.sep + "p2p.log"

            # 创建按时间旋转的日志处理器
            # - when='midnight': 每天午夜进行日志轮转
            # - interval=1: 每天轮转一次
            # - backupCount=2: 保留2天的日志备份
            # - encoding="utf-8": 使用UTF-8编码保存日志
            tf = logging.handlers.TimedRotatingFileHandler(
                filename=filename,
                when='midnight',
                interval=1,
                backupCount=2,
                encoding="utf-8"
            )

            # 定义日志格式
            # %(asctime)s: 日志时间
            # %(levelname)s: 日志级别
            # %(filename)s: 日志发生的文件名
            # %(funcName)s: 日志发生的函数名
            # %(lineno)d: 日志发生的行号
            # %(message)s: 日志消息
            fm = "%(asctime)s %(levelname)s %(filename)s %(funcName)s:%(lineno)d)] - %(message)s"

            # 创建格式化器对象
            fmt = logging.Formatter(fm)

            # 为日志处理器设置格式
            tf.setFormatter(fmt)

            # 为日志记录器添加处理器
            cls.log.addHandler(tf)

        # 返回配置好的日志记录器
        return cls.log


def html_parser(result):
    """
    解析HTML表单内容，提取表单提交所需的URL和字段数据

    参数:
        result: requests.Response对象，包含服务器响应

    返回:
        tuple: (目标URL, 表单数据字典)
    """
    # 1. 从JSON响应中获取HTML表单内容
    # - result.json(): 解析响应中的JSON数据
    # - .get("description"): 获取响应描述字段
    # - .get("form"): 提取包含HTML表单的内容
    html = result.json().get("description").get("form")

    # 2. 使用BeautifulSoup解析HTML
    # - 创建BeautifulSoup解析器对象
    # - "html.parser": 使用Python内置HTML解析器
    bs = BeautifulSoup(html, "html.parser")

    # 3. 获取表单提交的目标URL
    # - 查找<form>标签
    # - 获取其action属性值（表单提交地址）
    url = bs.form.get("action")

    # 4. 准备存储表单数据的字典
    data = {}

    # 5. 遍历表单中的所有<input>标签
    # - find_all("input"): 查找所有<input>元素
    # - 包括隐藏字段(hidden)、文本输入框等
    for input in bs.find_all("input"):
        # 6. 提取字段名称和值
        # - input.get("name"): 获取字段名称(name属性)
        # - input.get("value"): 获取字段值(value属性)
        data[input.get("name")] = input.get("value")

    # 7. 返回表单提交的目标URL和字段数据
    return url, data


def connect_mysql(sql):
    """
    连接MySQL数据库并执行SQL语句

    参数:
        sql: 要执行的SQL语句

    返回:
        - 对于SELECT查询：返回查询结果集
        - 对于其他操作：返回受影响的行数
    """
    conn = None
    cursor = None

    try:
        # 创建数据库连接
        conn = pymysql.connect(
            host="121.43.169.97",  # 数据库主机地址
            database="czbk_member",  # 数据库名称
            password="123456",  # 数据库密码
            user="student",  # 数据库用户名
            port="3306",  # 数据库端口
            charset="utf8",  # 字符集
            autocommit=True  # 自动提交事务
        )

        # 创建游标对象
        cursor = conn.cursor()

        # 执行SQL语句
        cursor.execute(sql)

        # 处理查询结果
        if sql.lower().split()[0] == "select":
            # 对于SELECT查询，返回所有结果
            return cursor.fetchall()
        else:
            # 对于其他操作，返回受影响的行数
            return cursor.rowcount

    except Exception as e:
        # 捕获并打印异常
        print("数据库操作出错：", e)
        # 重新抛出异常
        raise e

    finally:
        # 关闭游标
        if cursor:
            cursor.close()

        # 关闭数据库连接
        if conn:
            conn.close()

def clear_data():

    sql1="""
        DELETE info.* FROM mb_member AS mb INNER JOIN mb_member_info AS info ON info.member_id = mb.id WHERE mb.phone IN ("${phone1}", "${phone2}", "${phone3}", "${phone4}");
    """
    connect_mysql(sql1)

    sql2 = """
        DELETE login.* FROM mb_member AS mb INNER JOIN mb_member_login_log AS login ON login.member_id = mb.id WHERE mb.phone IN ("${phone1}", "${phone2}", "${phone3}", "${phone4}");
        """
    connect_mysql(sql2)

    sql3 = """
        DELETE FROM mb_member WHERE phone IN ("${phone1}", "${phone2}", "${phone3}", "${phone4}");
        """
    connect_mysql(sql3)

    sql4 = """
        DELETE FROM mb_member_register_log WHERE phone IN ("${phone1}", "${phone2}", "${phone3}", "${phone4}");
        """
    connect_mysql(sql4)


# 模块测试代码
if __name__ == '__main__':
    # 测试读取JSON文件功能
    print(read_json("register_login.json", "img_code"))